package org.jeecg.modules.network.network.tcp;

import com.zhouwr.common.enums.NetworkType;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.modules.device.listener.event.NetworkServerExceptionEvent;
import org.jeecg.modules.device.service.IDeviceInstanceService;
import org.jeecg.modules.network.network.NetworkConnectStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.net.SocketAddress;

@Slf4j
@Component
public class TcpServerConnectHandler extends ChannelInboundHandlerAdapter {

    private static TcpServerConnectHandler handler;
    @Autowired
    private IDeviceInstanceService instanceService;
    @Autowired
    private ApplicationEventPublisher publisher;

    @Override
    public void channelRegistered(ChannelHandlerContext ctx) throws Exception {
        log.info("===<<<设备连接之前的ctx.pipeline: " + ctx.pipeline().names());
//        ctx.pipeline().remove(this);
        Boolean b = NetworkConnectStore.addConnect(ctx, NetworkType.TCP_CLIENT);
        if (b) {
            super.channelRegistered(ctx);
        } else {
            super.channelUnregistered(ctx);
        }
        log.info("===>>>设备连接之后的ctx.pipeline: " + ctx.pipeline().names());
    }

    @Override
    public void channelUnregistered(ChannelHandlerContext ctx) throws Exception {
        log.info("===<<<设备断开之前的ctx.pipeline: " + ctx.pipeline().names());
        log.info("===<<<设备断开之前的NetworkConnectStore: " + NetworkConnectStore.getNetworkConnectMap());
        ctx.pipeline().remove(this);
        Channel channel = ctx.channel();
        SocketAddress adds = channel.remoteAddress();
        NetworkConnectStore.removeConnect(adds);
        log.info("===>>>设备断开之后的ctx.pipeline: " + ctx.pipeline().names());
        log.info("===>>>设备断开之后的NetworkConnectStore: " + NetworkConnectStore.getNetworkConnectMap());
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        log.warn("userEventTriggered >>> {}, {}", ctx, evt);
        ctx.close();
    }

    @AutoLog(value = "Tcp服务异常")
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
            throws Exception {
        log.warn("异常捕获 >>> {}, {}", ctx, cause);
//        super.exceptionCaught(ctx, cause);

        handler.publisher.publishEvent(new NetworkServerExceptionEvent(ctx.name(), cause.getMessage()));

        Channel channel = ctx.channel();
        if (channel.isActive()) {
            ctx.close();
        }
    }

    @PostConstruct
    public void init() {
        handler = this;
        handler.instanceService = this.instanceService;
        handler.publisher = this.publisher;
    }
}
